﻿//========================================
// All rights reserved (C) 2017-2100
// CLR 版本：	4.0.30319.42000
// 命名空间:	Network
// 文 件 名：	PacketWithProof
// 作    者：	WooG
// 联系方式：	wooglle@163.com
// 创建时间：	2018/3/25 16:32:00
//========================================
using System;
using System.Linq;
using System.Security.Cryptography;

namespace Network
{
    public struct PacketWithProof
    {
        public const int BytesCount = 1024;
        public const int PacketHeaderCount = 74;
        /// <summary>
        /// 发送方Guid， 16byte
        /// </summary>
        public Guid GuidSend { set; get; }
        /// <summary>
        /// 接收方Guid， 16byte
        /// </summary>
        public Guid GuidTarget { set; get; }
        /// <summary>
        /// 发送方IP地址， 4byte
        /// </summary>
        public byte[] IpSend { set; get; }
        /// <summary>
        /// 传送任务Guid， 16byte
        /// </summary>
        public Guid GuidTask { set; get; }
        /// <summary>
        /// 当前通讯包hash验证码， 16byte
        /// </summary>
        public byte[] HashCode { set; get; }
        /// <summary>
        /// 文件索引号，4byte
        /// </summary>
        public int FileIndex { set; get; }
        /// <summary>
        /// 任务当前文件索引号， 4byte
        /// </summary>
        public int MsgIndex { set; get; }
        /// <summary>
        /// 任务当前文件最大索引号， 4byte
        /// </summary>
        public int MsgTotal { set; get; }
        /// <summary>
        /// 当前通讯包消息位数，4byte
        /// </summary>
        public int MsgLenght { set; get; }
        /// <summary>
        /// 当前通讯包消息，最大长度950
        /// </summary>
        public byte[] MsgBytes { set; get; }

        public PacketWithProof(byte[] bytes)
        {
            GuidSend = new Guid(bytes.Skip(0).Take(16).ToArray());
            GuidTarget = new Guid(bytes.Skip(16).Take(16).ToArray());
            IpSend = bytes.Skip(32).Take(4).ToArray();
            GuidTask = new Guid(bytes.Skip(36).Take(16).ToArray());
            HashCode = bytes.Skip(42).Take(16).ToArray();
            FileIndex = BitConverter.ToInt32(bytes.Skip(58).Take(4).ToArray(), 0);
            MsgIndex = BitConverter.ToInt32(bytes.Skip(62).Take(4).ToArray(), 0);
            MsgTotal = BitConverter.ToInt32(bytes.Skip(66).Take(4).ToArray(), 0);
            MsgLenght = (int)BitConverter.ToInt16(bytes.Skip(70).Take(4).ToArray(), 0);
            MsgBytes = bytes.Skip(PacketHeaderCount).Take(MsgLenght).ToArray();
        }

        public PacketWithProof(Guid guidS, Guid guidT, byte[] ip, Guid guidTask, int indexFile, int indexMsg, int totalMsg, byte[] byteMsg)
        {
            GuidSend = guidS;
            GuidTarget = guidT;
            IpSend = ip;
            GuidTask = guidTask;
            HashCode = new MD5CryptoServiceProvider().ComputeHash(byteMsg);
            FileIndex = indexFile;
            MsgIndex = indexMsg;
            MsgTotal = totalMsg;
            MsgLenght = byteMsg.Length;
            MsgBytes = byteMsg;
        }

        public byte[] ToBytes()
        {
            byte[] b = new byte[BytesCount];
            try
            {
                Buffer.BlockCopy(GuidSend.ToByteArray(), 0, b, 0, 16);
                Buffer.BlockCopy(GuidTarget.ToByteArray(), 0, b, 16, 16);
                Buffer.BlockCopy(IpSend, 0, b, 32, 4);
                Buffer.BlockCopy(GuidTask.ToByteArray(), 0, b, 36, 16);
                Buffer.BlockCopy(HashCode, 0, b, 52, 16);
                Buffer.BlockCopy(BitConverter.GetBytes(FileIndex), 0, b, 68, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(MsgIndex), 0, b, 72, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(MsgTotal), 0, b, 76, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(MsgLenght), 0, b, 80, 4);
                Buffer.BlockCopy(MsgBytes, 0, b, PacketHeaderCount, MsgLenght);
            }
            catch { }
            return b;
        }
    }
}
